﻿using System;
using System.Collections.Generic;
using FBGraph.Controllers.Connections.Users;
using FBGraph.Models;

namespace FBGraph.Controllers
{
    /// <summary>Provides access to <see cref="User" /> profiles and connections specific to user Graph API objects</summary>
    public class UsersController : FBGraphController, IFBGraphPrimaryController<User>, IFBGraphSearchController<User>
    {
        /// <summary>Initializes an instance of <see cref="UsersController" />.</summary>
        /// <param name="context">A reference to the containing <see cref="IFBGraphContext" /> implementation.</param>
        public UsersController(IFBGraphContext context) : base(context) { }

        /// <summary>Initializes subcontrollers contained by <see cref="UsersController" />.</summary>
        protected override void InitSubcontrollers()
        {
            this.Activities = new ActivitiesController(Context);
            this.Albums = new AlbumsController(Context);
            this.Books = new BooksController(Context);
            this.Events = new EventsController(Context);
            this.Feed = new FeedController(Context);
            this.Friends = new FriendsController(Context);
            this.Groups = new GroupsController(Context);
            this.Home = new HomeController(Context);
            this.Inbox = new InboxController(Context);
            this.Interests = new InterestsController(Context);
            this.Likes = new LikesController(Context);
            this.Links = new LinksController(Context);
            this.Movies = new MoviesController(Context);
            this.Music = new MusicController(Context);
            this.Notes = new NotesController(Context);
            this.Outbox = new OutboxController(Context);
            this.Photos = new PhotosController(Context);
            this.Posts = new PostsController(Context);
            this.Statuses = new StatusesController(Context);
            this.Tagged = new TaggedController(Context);
            this.Television = new TelevisionController(Context);
            this.Updates = new UpdatesController(Context);
            this.Videos = new VideosController(Context);
        }

        /// <summary>Gets a reference to a <see cref="ActivitiesController" />, which provides access to the activities connection for users.</summary>
        public IFBGraphConnectionController<Page> Activities { get; private set; }

        /// <summary>Gets a reference to a <see cref="AlbumsController" />, which provides access to the albums connection for users.</summary>
        public IFBGraphConnectionController<Album> Albums { get; private set; }

        /// <summary>Gets a reference to a <see cref="BooksController" />, which provides access to the books connection for users.</summary>
        public IFBGraphConnectionController<Page> Books { get; private set; }

        /// <summary>Gets a reference to a <see cref="EventsController" />, which provides access to the events connection for users.</summary>
        public IFBGraphConnectionController<Event> Events { get; private set; }

        /// <summary>Gets a reference to a <see cref="FeedController" />, which provides access to the feed connection for users.</summary>
        public IFBGraphConnectionController<Post> Feed { get; private set; }

        /// <summary>Gets a reference to a <see cref="FriendsController" />, which provides access to the friends connection for users.</summary>
        public IFBGraphConnectionController<User> Friends { get; private set; }

        /// <summary>Gets a reference to a <see cref="GroupsController" />, which provides access to the groups connection for users.</summary>
        public IFBGraphConnectionController<Group> Groups { get; private set; }

        /// <summary>Gets a reference to a <see cref="HomeController" />, which provides access to the home connection for users.</summary>
        public HomeController Home { get; private set; }

        /// <summary>Gets a reference to a <see cref="InboxController" />, which provides access to the inbox connection for users.</summary>
        public IFBGraphConnectionController<MailboxItem> Inbox { get; private set; }

        /// <summary>Gets a reference to a <see cref="InterestsController" />, which provides access to the interests connection for users.</summary>
        public IFBGraphConnectionController<Page> Interests { get; private set; }

        /// <summary>Gets a reference to a <see cref="LikesController" />, which provides access to the likes connection for users.</summary>
        public IFBGraphConnectionController<Page> Likes { get; private set; }

        /// <summary>Gets a reference to a <see cref="LinksController" />, which provides access to the links connection for users.</summary>
        public IFBGraphConnectionController<Post> Links { get; private set; }

        /// <summary>Gets a reference to a <see cref="MoviesController" />, which provides access to the movies connection for users.</summary>
        public IFBGraphConnectionController<Page> Movies { get; private set; }

        /// <summary>Gets a reference to a <see cref="MusicController" />, which provides access to the music connection for users.</summary>
        public IFBGraphConnectionController<Page> Music { get; private set; }

        /// <summary>Gets a reference to a <see cref="NotesController" />, which provides access to the notes connection for users.</summary>
        public IFBGraphConnectionController<Note> Notes { get; private set; }

        /// <summary>Gets a reference to a <see cref="OutboxController" />, which provides access to the outbox connection for users.</summary>
        public IFBGraphConnectionController<MailboxItem> Outbox { get; private set; }

        /// <summary>Gets a reference to a <see cref="PhotosController" />, which provides access to the photos connection for users.</summary>
        public IFBGraphConnectionController<Photo> Photos { get; private set; }

        /// <summary>Gets a reference to a <see cref="PostsController" />, which provides access to the posts connection for users.</summary>
        public IFBGraphConnectionController<Post> Posts { get; private set; }

        /// <summary>Gets a reference to a <see cref="StatusesController" />, which provides access to the statuses connection for users.</summary>
        public IFBGraphConnectionController<StatusMessage> Statuses { get; private set; }

        /// <summary>Gets a reference to <see cref="TaggedController" />, which provides access to the tagged connection for users.</summary>
        public IFBGraphConnectionController<Post> Tagged { get; private set; }

        /// <summary>Gets a reference to a <see cref="TelevisionController" />, which provides access to the television connection for users.</summary>
        public IFBGraphConnectionController<Page> Television { get; private set; }

        /// <summary>Gets a reference to a <see cref="UpdatesController" />, which provides access to the updates connection for users.</summary>
        public IFBGraphConnectionController<MailboxItem> Updates { get; private set; }

        /// <summary>Gets a reference to a <see cref="VideosController" />, which provides access to the videos connection for users.</summary>
        public IFBGraphConnectionController<Video> Videos { get; private set; }

        /// <summary>Gets the currently authenticated <see cref="User" />.</summary>
        /// <returns>A <see cref="User" /> object that has been deserialized from the JSON response of the GET request.</returns>
        public User Get()
        {
            return this.Get((Object)null);
        }

        /// <summary>Gets the <see cref="User" /> with the specified <paramref name="id" />.</summary>
        /// <param name="id">The Graph identifier or alias of the <see cref="User" /> that should be retrieved. If <paramref name="id" /> is <c>null</c> or
        /// <see cref="String.Empty" />, the alias <c>me</c> is used to retrieve the current user.</param>
        /// <returns>A <see cref="User" /> object that has been deserialized from the JSON response of the GET request.</returns>
        public User Get(Object id)
        {
            if (id == null || (id is String && (String)id == String.Empty)) id = "me";

            return FBGraphPrimaryControllerExtensions.Get(this, id);
        }

        #region [ IFBGraphSearchController<User> Members ]

        String IFBGraphSearchController<User>.SearchType
        {
            get { return "user"; }
        }

        #endregion
    }
}